package com.rabbitmq.provider;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @作者: 林江
 * @创建时间: 2023/11/28
 * @功能:
 */
public class SimpleProvider {
    CachingConnectionFactory factory = new CachingConnectionFactory();

    public SimpleProvider() {
        factory.setHost("192.168.32.128");
        factory.setVirtualHost("/");
        factory.setUsername("admin");
        factory.setPassword("123456");
        // 设置publisher_confirm
        factory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
        createDelay02();
    }

    public void create() {
        RabbitAdmin admin = new RabbitAdmin(factory);
        // 声明一个直连交换机
        Exchange ex = new DirectExchange("test_rabbitAdmin");
        admin.declareExchange(ex);
        // 创建队列
        Queue q = new Queue("test03", true);
        admin.declareQueue(q);

        // 创建绑定关系
        Binding binding = BindingBuilder.bind(q).to(ex).with("amqpAdmin").and(new HashMap<>());
        admin.declareBinding(binding);
    }

    // 创建死信队列
    public void createDLX() {
        RabbitAdmin admin = new RabbitAdmin(factory);
        // 创建死信交换机 -- 实际上就是普通交换机
        Exchange dlx = new TopicExchange("DLX");
        admin.declareExchange(dlx);
        // 创建死信队列
        Queue dlxQ = new Queue("test07_dlx", true);
        admin.declareQueue(dlxQ);
        // 创建绑定关系
        Binding dlxBinding = BindingBuilder.bind(dlxQ).to(dlx).with("dlx.#").and(new HashMap<>());
        admin.declareBinding(dlxBinding);

        // 声明一个直连交换机
        Exchange ex = new DirectExchange("test_DLX");
        admin.declareExchange(ex);
        // 创建队列
        Map<String, Object> args = new HashMap();
        args.put("x-dead-letter-exchange", "DLX"); // 为正常的队列绑定交换机
        args.put("x-dead-letter-routing-key", "dlx.key"); // 正常队列投递消息到交换机时的路由key
        args.put("x-message-ttl", 10000); // 设置队列的过期时间
        args.put("x-max-length", 10); // 设置队列的最大能够保存消息的多少。

        Queue q = new Queue("test06", true, false, false, args);
        admin.declareQueue(q);
        // 创建绑定关系
        Binding binding = BindingBuilder.bind(q).to(ex).with("test_dlx_key").and(new HashMap<>());
        admin.declareBinding(binding);
    }

    // 创建延时队列 = TTL消息 + 私信队列
    public void createDelay01() {
        RabbitAdmin admin = new RabbitAdmin(factory);
//        // 创建死信交换机 -- 实际上就是普通交换机
//        Exchange dlx = new TopicExchange("DLX");
//        admin.declareExchange(dlx);
//        // 创建死信队列
//        Queue dlxQ = new Queue("test07_dlx", true);
//        admin.declareQueue(dlxQ);
//        // 创建绑定关系
//        Binding dlxBinding = BindingBuilder.bind(dlxQ).to(dlx).with("dlx.#").and(new HashMap<>());
//        admin.declareBinding(dlxBinding);

        // 声明一个直连交换机
        Exchange ex = new DirectExchange("test_delay");
        admin.declareExchange(ex);
        // 创建队列
        Map<String, Object> args = new HashMap();
        args.put("x-dead-letter-exchange", "DLX"); // 为正常的队列绑定交换机
        args.put("x-dead-letter-routing-key", "dlx.delay"); // 正常队列投递消息到交换机时的路由key
//        args.put("x-message-ttl", 10000); // 设置队列的过期时间
//        args.put("x-max-length", 10); // 设置队列的最大能够保存消息的多少。

        Queue q = new Queue("test08", true, false, false, args);
        admin.declareQueue(q);
        // 创建绑定关系
        Binding binding = BindingBuilder.bind(q).to(ex).with("test_delay_key").and(new HashMap<>());
        admin.declareBinding(binding);
    }

    // 创建延时队列，使用插件的形式：rabbitmq_delayed_message_exchange
    public void createDelay02() {
        RabbitAdmin admin = new RabbitAdmin(factory);
        // 声明一个自定义交换机
        Map<String, Object> args = new HashMap();
        // 声明延时交换机的类型
        args.put("x-delayed-type", "direct");

        Exchange ex = new CustomExchange("test_delay_plugin", "x-delayed-message", true, false, args);
        admin.declareExchange(ex);
        // 创建队列
        Queue q = QueueBuilder.durable("test09").withArguments(args).build();
        admin.declareQueue(q);
        // 创建绑定关系
        Binding binding = BindingBuilder.bind(q).to(ex).with("test_delay_plugin_key").and(new HashMap<>());
        admin.declareBinding(binding);
    }

    private void send() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(factory);
        rabbitTemplate.setConfirmCallback(((correlationData, ack, cause) -> {
            System.out.println(correlationData);
            System.out.println(ack);
            System.out.println(cause);
        }));

        rabbitTemplate.convertAndSend("test_rabbitAdmin", "amqpAdmin", "使用amqpAdmin。。。。");
    }

    public static void main(String[] args) {
        SimpleProvider demo = new SimpleProvider();
        demo.createDLX();
    }
}
